# -*- coding: utf-8 -*-
"""
小红书帖子创作与发布助手
基于AgentScope框架和xiaohongshu-mcp服务
"""

import asyncio
from typing import Dict, Any, List
from pydantic import BaseModel, Field
from agentscope.agent import ReActAgent
from agentscope.formatter import OpenAIChatFormatter
from agentscope.mcp import HttpStatelessClient
from agentscope.memory import InMemoryMemory
from agentscope.message import Msg
from agentscope.model import OpenAIChatModel
from agentscope.tool import Toolkit

class XiaohongshuPost(BaseModel):
    """小红书帖子内容模型"""
    title: str = Field(description="吸引眼球的标题，带emoji")
    content: str = Field(description="正文内容，符合小红书风格：亲切、口语化、带标签")
    hashtags: List[str] = Field(description="相关话题标签，如 #西湖 #杭州旅行")


class XiaohongshuPoster:
    """小红书帖子创作与发布助手"""

    def __init__(
        self
    ):

        # 初始化MCP客户端：指向xiaohongshu-mcp服务
        self.mcp_client = HttpStatelessClient(
            name="xiaohongshu_mcp",
            transport="streamable_http",
            url="http://localhost:18060/mcp",  # 假设xiaohongshu-mcp运行在此端口
        )

        self.toolkit = Toolkit()
        self.agent = None

    async def initialize_tools(self) -> None:
        """初始化小红书MCP工具"""
        await self.toolkit.register_mcp_client(self.mcp_client)
        tools = self.toolkit.get_json_schemas()
        print(f"已注册 {len(tools)} 个小红书MCP工具")
        for tool in tools:
            name = tool["function"]["name"]
            desc = tool["function"].get("description", "")
            print(f"- {name}: {desc}")

    async def initialize_agent(self, model_name, api_key, base_url) -> None:
        """初始化小红书创作Agent"""
        if not self.toolkit.get_json_schemas():
            await self.initialize_tools()

        self.agent = ReActAgent(
            name="XiaohongshuCreator",
            sys_prompt=(
                "你是一位资深小红书博主，擅长创作高互动、高颜值的旅行/生活类笔记。\n"
                "你的任务是：\n"
                "1. 根据用户提供的图片主题（如'西湖美景'）和风格要求，创作一篇符合小红书调性的帖子；\n"
                "2. 标题要吸睛（可带🔥/✨/📸等emoji），正文要亲切、有代入感、带实用信息；\n"
                "3. 结尾添加5-8个精准话题标签；\n"
                "4. 你**必须先调用工具检查登录状态**，再创作内容，最后调用发布工具。\n"
                "5. 用户也可以自己写文案，你需要发布该文案，不要做内容的修改"
                "可用工具：\n"
                "\n".join([f"- {tool['function']['name']}: {tool['function'].get('description', '')}"
                           for tool in self.toolkit.get_json_schemas()])
            ),
            model=OpenAIChatModel(
                model_name=model_name,
                api_key=api_key,
                client_args={"base_url": base_url},
            ),
            memory=InMemoryMemory(),
            formatter=OpenAIChatFormatter(),
            toolkit=self.toolkit,
            parallel_tool_calls=True,
        )

    async def create_and_publish_post(
        self,
        model_name: str,
        api_key: str,
        base_url: str,
        image_paths: List[str],
        theme: str = "西湖美景",
        select_type: str = "create_and_publish",
    ) -> Dict[str, Any]:
        """创作并发布小红书帖子"""
        if self.agent is None:
            await self.initialize_agent(model_name, api_key, base_url)
            
        if select_type == "create_and_publish":
            user_request = (
                f"请帮我写一篇小红书帖子，主题是'{theme}'，配图文件路径为：{', '.join(image_paths)}。\n"
                f"帖子风格要求：符合小红书文案风格，吸引人，带emoji和实用旅行建议。\n"
                "请按以下流程执行：\n"
                "1. 先检查小红书登录状态；\n"
                "2. 创作标题、正文和话题标签；\n"
                "3. 调用发布工具发布帖子。"
            )
        elif select_type == "publish":
            user_request = (
                f"我的文案如下： {theme}。配图文件路径为：{', '.join(image_paths)}。\n"
                "请按以下流程执行：\n"
                "1. 先检查小红书登录状态；\n"
                "2. 调用发布工具发布帖子。"
            )

        # 调用Agent（结构化输出暂不用于最终发布，仅用于中间创作）
        res = await self.agent(
            Msg("user", user_request, "user"),
            # 注意：由于最终需调用工具发布，structured_output 可能干扰工具调用流程
            # 因此此处不强制结构化输出，让Agent自由调用工具
        )

        # 返回最终结果（可从memory或res中提取）
        return {"status": "completed", "message": "帖子已尝试发布，请检查小红书账号"}


async def main():
    try:
        #openai兼容格式
        model_name="XXX"
        api_key="XXX"
        base_url="XXX"

        print("=== 小红书帖子创作与发布助手 ===")
        poster = XiaohongshuPoster()

        image_paths = [
            r"path1\test1.jpeg",
            r"path2\test2.jpeg",
        ]

        print("正在创作并发布小红书帖子...")
        theme = f"标题：西湖好美啊，正文：西湖是中国的一个热门景点，我很想去看。话题标签：#西湖#杭州"
        select_type = "publish"
        result = await poster.create_and_publish_post(
            model_name=model_name,
            api_key=api_key,
            base_url=base_url,
            image_paths=image_paths,
            theme=theme,
            select_type=select_type,
        )

        print("\n✅ 任务完成！")
        print(f"结果: {result['message']}")

    except* Exception as eg:  # 使用 except* 捕获 ExceptionGroup
        print(f"❌ 执行出错 (ExceptionGroup):")
        for i, exc in enumerate(eg.exceptions, 1):
            print(f"  子异常 {i}: {type(exc).__name__}: {exc}")


if __name__ == "__main__":
    asyncio.run(main())
